Attribute VB_Name = "vdp"
Option Explicit

Private line As Long 'Current Line Number.

Public ShowOnlyleft As Boolean
Public Flipper3D As Boolean
Public Disable3D As Boolean
Public fastforward As Boolean
Public latch As Long 'gg vdp latch
Public BG_Color As Integer 'for layer disabling
Public bg_priority() As Long 'Background Priorites.
Public command_byte As Long 'Command Word First Byte Latch.
Public counter As Long 'Vertical Line Interrupt Counter.
Public CRAM() As Long 'Colour RAM.
Public display() As Long 'Pointer to Current Display.
Public first_byte As Long 'First or Second Byte of Command Word.
Public frameint As Long 'Frame interrupt Pending.
Public HACK_Spider As Boolean 'vdp hack for spiderman game
Public Layerdrawbg As Boolean 'draw bg layer?
Public LayerDrawSprites As Boolean 'draw sprites layer?
Public LimitSprites As Boolean 'for sprite limiting
Public lineint As Long 'Line interrupt Pending.
Public location As Long 'Location in VRAM.
Public myBMP As BITMAPINFO
Public operation As Long 'Store type of operation taking place.
Public read_buffer As Long 'Buffer VRAM Reads.
Public SMS_PALETTE(63) As Long 'SMS Color palette
Public GG_PALETTE(4095) As Long 'gg Color palette
Public spritecol() As Long 'Sprite Collisions.
Public status As Long 'Status Register.
Public vdpreg() As Long 'VDP Registers.
Public VRAM() As Long 'Video RAM.
Public Zoom_Size As Integer 'tells how big the virtual display is

Public Const SMS_WIDTH As Long = 256& 'SMS Screen width
Public Const SMS_HEIGHT As Long = 192& 'SMS Screen height
Public Const GG_WIDTH As Long = 160 'GG Screen width
Public Const GG_HEIGHT As Long = 144& 'GG Screen height
'#define SMS_SCREEN_WIDTH  256
'#define SMS_SCREEN_HEIGHT 192
'#define GG_SCREEN_WIDTH   160
'#define GG_SCREEN_HEIGHT  144

Public H_START As Long   'Horizontal viewport start
Public H_END As Long  'Horizontal viewport end

Public Declare Function StretchDIBits Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal wSrcWidth As Long, ByVal wSrcHeight As Long, lpBits As Any, lpBitsInfo As BITMAPINFO, ByVal wUsage As Long, ByVal dwRop As Long) As Long

Public Type BITMAPINFOHEADER
  biSize As Long
  biWidth As Long
  biHeight As Long
  biPlanes As Integer
  biBitCount As Integer
  biCompression As Long
  biSizeImage As Long
  biXPelsPerMeter As Long
  biYPelsPerMeter As Long
  biClrUsed As Long
  biClrImportant As Long
End Type

Public Type BITMAPINFO
  bmiHeader As BITMAPINFOHEADER
  bmiColor0 As Long
  bmiColor1 As Long
  bmiColor2 As Long
End Type
Public Sub blitscreen()
    
  If IsGameGear Then Call vdp.drawbordergg

  If IsFullScreen Then
    If Disable3D = True Then
      If Flipper3D = False And ShowOnlyleft = False Then
        Call StretchDIBits(frmFullScreen.picScreen.hdc, 0&, 0&, frmFullScreen.picScreen.ScaleWidth, frmFullScreen.picScreen.ScaleHeight, 0&, 0&, SMS_WIDTH, SMS_HEIGHT, display(0&), myBMP, 0&, vbSrcCopy)
      End If
      If Flipper3D = True And ShowOnlyleft = True Then
        Call StretchDIBits(frmFullScreen.picScreen.hdc, 0&, 0&, frmFullScreen.picScreen.ScaleWidth, frmFullScreen.picScreen.ScaleHeight, 0&, 0&, SMS_WIDTH, SMS_HEIGHT, display(0&), myBMP, 0&, vbSrcCopy)
      End If
      Flipper3D = Not Flipper3D
    Else
      Call StretchDIBits(frmFullScreen.picScreen.hdc, 0&, 0&, frmFullScreen.picScreen.ScaleWidth, frmFullScreen.picScreen.ScaleHeight, 0&, 0&, SMS_WIDTH, SMS_HEIGHT, display(0&), myBMP, 0&, vbSrcCopy)
    End If
    If AVIRecording = True And AVIFlipper = False Then
      Call SavePicture(exportbmp(frmFullScreen.picScreen), AVITemp)
      Call bmp.CreateFromFile(AVITemp)
      Call AVIStreamWrite(psCompressed, AVIFrames, 1, bmp.PointerToBits, bmp.SizeImage, AVIIF_KEYFRAME, ByVal 0&, ByVal 0&)
      AVIFrames = AVIFrames + 1
    End If
    AVIFlipper = Not AVIFlipper
  Else
    If Disable3D = True Then
      If Flipper3D = False And ShowOnlyleft = False Then
        Call StretchDIBits(frmSMS.picScreen.hdc, 0&, 0&, frmSMS.picScreen.ScaleWidth, frmSMS.picScreen.ScaleHeight, 0&, 0&, SMS_WIDTH, SMS_HEIGHT, display(0&), myBMP, 0&, vbSrcCopy)
      End If
      If Flipper3D = True And ShowOnlyleft = True Then
        Call StretchDIBits(frmSMS.picScreen.hdc, 0&, 0&, frmSMS.picScreen.ScaleWidth, frmSMS.picScreen.ScaleHeight, 0&, 0&, SMS_WIDTH, SMS_HEIGHT, display(0&), myBMP, 0&, vbSrcCopy)
      End If
      Flipper3D = Not Flipper3D
    Else
      Call StretchDIBits(frmSMS.picScreen.hdc, 0&, 0&, frmSMS.picScreen.ScaleWidth, frmSMS.picScreen.ScaleHeight, 0&, 0&, SMS_WIDTH, SMS_HEIGHT, display(0&), myBMP, 0&, vbSrcCopy)
    End If
    If AVIRecording = True And AVIFlipper = False Then
      Call SavePicture(exportbmp(frmSMS.picScreen), AVITemp)
      Call bmp.CreateFromFile(AVITemp)
      Call AVIStreamWrite(psCompressed, AVIFrames, 1, bmp.PointerToBits, bmp.SizeImage, AVIIF_KEYFRAME, ByVal 0&, ByVal 0&)
      AVIFrames = AVIFrames + 1
    End If
    AVIFlipper = Not AVIFlipper
  End If
  
End Sub
Public Sub drawbordergg() 'draws the border for game gear games

  If Not DoGameGearBorder Then
    Exit Sub
  End If

  Dim b As Long, a As Long, X As Long

  X& = 0

  For b& = 0 To 23
    For a& = 0 To 255
      display(X& + a&) = vbBlack
    Next a&
    X& = X& + 256
  Next b&

  X& = UBound(display) - 256

  For b& = 0 To 24
    For a& = 0 To 255
      display(X& + a&) = vbBlack
    Next a&
    X& = X& - 256
  Next b&

  X& = 0
  For b& = 0 To 191
    For a& = 0 To 47
      display(X + a&) = vbBlack
    Next a&
    For a& = 255 To 208 Step -1
      display(X + a&) = vbBlack
    Next a&
    X& = X& + 256
  Next b&

End Sub
Public Sub reset() 'reset vdp

  ReDim VRAM(16385&) As Long 'Clear VRAM memory.
  ReDim CRAM(64&) As Long 'Clear CRAM memory.
  ReDim vdpreg(16&) As Long 'Clear VDPREG.
  ReDim bg_priority(270) As Long 'Clear bg priorities.
  ReDim spritecol(SMS_WIDTH) As Long 'Clear sprite collisions
  ReDim display(49408) As Long 'clear video shit?
  
  first_byte = True
  lineint = False
  frameint = False
  location = 0&
  counter = 0&
  status = 0&
  
  vdpreg(2) = 14& 'SMS Bios Value.
  vdpreg(5) = 126& 'SMS Bios Value.
  vdpreg(6) = 255& 'SMS Bios Value.
  vdpreg(10) = 1& 'SMS Bios Value.
  
  irqsetLine = False
  
  'vbt to do later
  'If IsGameGear Then
    'H_START = 48&
    'H_END = GG_WIDTH
  'Else
    H_START = 0&
    H_END = SMS_WIDTH
  'End If

End Sub
Public Function getvcount() As Long 'Read Vertical Port.

  If (line > &HDA&) Then
    getvcount = line - 6
  Else
    getvcount = line
  End If
  
End Function
Public Sub controlwrite(value As Long) 'Write to VDP Control Port (BF).

  If (first_byte) Then 'Store First Byte of Command Word
    first_byte = False
    command_byte = value
    location = (location And &H3F00&) Or (value And &HFF&)
    Exit Sub
  End If
    
  first_byte = True
        
  If (ShiftRight(value, 4&) = 8&) Then 'Set VDP Register
  
    vdpreg(value And 15&) = command_byte
    
    If (lineint) Then
      If (((value And 15) = 0) And ((command_byte And 16) = 0)) Then
        irqsetLine = False
      ElseIf (((value And 15) = 0) And ((command_byte And 16) = 16)) Then
        irqsetLine = True
      End If
    End If
    
    If (frameint) Then
      If (((value And 15) = 1) And ((command_byte And 32) = 0)) Then
        irqsetLine = False
      ElseIf (((value And 15) = 1) And ((command_byte And 32) = 32)) Then
        irqsetLine = True
      End If
    End If
  
  Else
  
    'Operation from B6 + B7
    operation = ShiftRight(value, 6&)

    'Set location in VRAM
    location = (location And &HFF&) Or ShiftLeft(value And &H3F&, 8&)
    
    If (operation = 0&) Then
      read_buffer = VRAM(location)
      If (location > 16383&) Then location = 0& Else location = location + 1&
    End If

  End If
  
End Sub
Public Function controlread() As Long 'Read VDP Control Port (BF).
  
  Dim statuscopy As Long
  
  first_byte = True
  statuscopy = status
  status = status And Not &H80& And Not &H40& And Not &H20&
  
  'Clear pending interrupts
  lineint = False
  frameint = False
  
  irqsetLine = False 'Clear IRQ Line

  controlread = statuscopy

End Function
Public Sub datawrite(value As Long) 'Write to VDP Data Port (BE).

  first_byte = True
  
  Select Case (operation)
    Case 0& To 2& 'VRAM Write
      VRAM(location) = value
    Case 3& 'CRAM Write
      If IsGameGear Then
        If ((location And 1) = 0) Then
          latch = value
        Else
          value = value And &HF&
          CRAM(rshiftlong(location, 1) And &H1F&) = GG_PALETTE(lshiftlong(value, 8) Or latch)
        End If
      Else
        CRAM(location And &H1F&) = SMS_PALETTE(value And &H3F&)
      End If
  End Select
  
  If (location < 16383&) Then location = location + 1& Else location = 0&
    
End Sub
Public Function dataread() As Long 'Read VDP Data Port (BE).
  
  first_byte = True
  
  'VRAM Read
  If (operation < 2&) Then
    dataread = read_buffer
    read_buffer = VRAM(location)
  End If
  
  If (location < 16383&) Then location = location + 1& Else location = 0&
                        
End Function
Public Sub drawline(lineno As Long) 'Render Line of SMS/GG Display.
    
  ReDim spritecol(SMS_WIDTH) As Long
  
  If Not ((Not (vdpreg(1) And 64)) Or (((vdpreg(2) And 1) = 0) And (Not IsGameGear))) Then
'vbt : previous test
'If (Not (vdpreg(1) And 64) = 0) Then
    If IsGameGear Then
      drawbggg (lineno)
    Else
      drawbgsms (lineno)
    End If
    drawsprite (lineno)
  End If
    
  If Not IsGameGear Then
    If ((vdpreg(0) And &H20&) = &H20&) Then blankcolumn (lineno)
  End If

End Sub

Private Sub drawbgsms(lineno As Long) 'Render Line of Background Layer.

  Dim X As Long, Y As Long, bgt As Long, pattern As Long, pal As Long, hscroll As Long, start_column As Long, start_row As Long, tilex As Long, tiley As Long, tile_props As Long, firstbyte As Long, secondbyte As Long, priority As Long, address As Long, xpos As Long, row_precal As Long, address0 As Long, address1 As Long, address2 As Long, address3 As Long, bit As Long, a As Long, colour As Long

  Y = lineno
  bgt = ShiftLeft(vdpreg(2&) And 15& And Not 1&, 10&)
 
  '// Vertical Scroll Fine Tune
  If (Not vdpreg(9&) = 0&) Then lineno = lineno + (vdpreg(9&) And 7&)

  '// Vertical Scroll; Row of Tile to Plot.
  start_row = lineno
  tiley = (lineno And 7&)

  '// Top Two Rows Not Affected by Horizontal Scrolling (SMS Only)
  If (((vdpreg(0&) And 64&) = 64&) And (Y < 16&)) Then
    hscroll = 0&
  ElseIf (Not vdpreg(8&) = 0&) Then
    hscroll = vdpreg(8&) And 7&
    start_column = 32& - ShiftRight(vdpreg(8&), 3&)
  End If
  
  'If (setup.is_gg) Then... [Add coding for GameGear Here]
  
  '// Adjust Vertical Scroll
  If (Not vdpreg(9&) = 0&) Then
    start_row = start_row + (vdpreg(9&) And 248&)
    If (start_row > 223&) Then start_row = start_row - 224&
  End If

  '// Cycle through background table
  For X = H_START To H_END Step 8&
    
    '// wraps at 32
    If (start_column = 32&) Then start_column = 0&
            
    '// Rightmost 8 columns Not Affected by Vertical Scrolling
    If (((vdpreg(0&) And 128&) = 128&) And (X > 184&)) Then
      start_row = Y
      tiley = (Y And 7&)
    End If

    '// Get the two bytes from VRAM containing the tile's properties
    tile_props = bgt + ShiftLeft(start_column, 1&) + ShiftLeft(start_row - tiley, 3&)
    firstbyte = VRAM(tile_props) ' And 255&
    secondbyte = VRAM(tile_props + 1) ' And 255&
    
    '// Priority of tile
    priority = secondbyte And 16&
                
    '// Select Palette (Extended Colors).
    If ((secondbyte And 8&) = 8&) Then pal = 16& Else pal = 0&
    
    '// Pattern Number
    pattern = ShiftLeft(firstbyte + ShiftLeft(secondbyte And 1&, 8&), 5&)
        
    '// Vertical Tile Flip
    If ((secondbyte And 4&) = 0&) Then
      address = ShiftLeft(tiley, 2&) + pattern
    Else
      address = ShiftLeft(7& - tiley, 2&) + pattern
    End If
    
    '// Rowcount
    tilex = 0&
    
    '// Precalculate Y Position
    row_precal = ShiftLeft(Y, 8&)
    
    address0 = VRAM(address)
    address1 = VRAM(address + 1&)
    address2 = VRAM(address + 2&)
    address3 = VRAM(address + 3&)
    
    '//Plots row of 8 pixels
    bit = 128&
    
    Do
    
      '// Horizontal Tile Flip
      If ((secondbyte And 2&) = 0&) Then
        xpos = tilex + hscroll + X
      Else
        xpos = 7& - tilex + hscroll + X
      End If
      
      colour = 0 '// Set Colour of Pixel (0-15)

      If (Not (address0 And bit) = 0&) Then colour = colour Or 1&
      If (Not (address1 And bit) = 0&) Then colour = colour Or 2&
      If (Not (address2 And bit) = 0&) Then colour = colour Or 4&
      If (Not (address3 And bit) = 0&) Then colour = colour Or 8&
                
      '// Set Priority Array (Sprites over background tile)
      If (priority = 16&) And (Not colour = 0&) Then
        bg_priority(xpos) = True
      Else
        bg_priority(xpos) = False
      End If
      
      If Layerdrawbg Then 'checks whether to draw the bg from ram
        display(xpos + row_precal) = CRAM(colour + pal)
      Else 'or draw user-defined color for layer disabling
        display(xpos + row_precal) = QBColor(BG_Color%)
      End If

      tilex = tilex + 1&
      bit = ShiftRight(bit, 1&)

    Loop Until bit = 0&

    start_column = start_column + 1&
      
  Next X

End Sub




Private Sub drawbggg(lineno As Long) 'Render Line of Background Layer.

  Dim X As Long, Y As Long, bgt As Long, pattern As Long, pal As Long, hscroll As Long, start_column As Long, start_row As Long, tilex As Long, tiley As Long, tile_props As Long, firstbyte As Long, secondbyte As Long, priority As Long, address As Long, xpos As Long, row_precal As Long, address0 As Long, address1 As Long, address2 As Long, address3 As Long, bit As Long, a As Long, colour As Long

  Y = lineno
  bgt = ShiftLeft(vdpreg(2&) And 15& And Not 1&, 10&)
  
  '// Vertical Scroll Fine Tune
  If (Not vdpreg(9&) = 0&) Then lineno = lineno + (vdpreg(9&) And 7&)
  
  '// Vertical Scroll; Row of Tile to Plot.
  start_row = lineno: tiley = (lineno And 7&)
  
  '// Top Two Rows Not Affected by Horizontal Scrolling (SMS Only)
  hscroll = vdpreg(8&) And 7&
  start_column = 32& - (ShiftRight(vdpreg(8&), 3&))
  'start_column = 0&
  
  'If (setup.is_gg) Then... [Add coding for GameGear Here]
  
  '// Adjust Vertical Scroll
  If (Not vdpreg(9&) = 0&) Then
    start_row = start_row + (vdpreg(9&) And 248&)
    If (start_row > 223&) Then start_row = start_row - 224&
  End If
  
  '// Cycle through background table
  For X = H_START To H_END Step 8&
    
    '// wraps at 32
    If (start_column = 32&) Then start_column = 0&
    
    '// Get the two bytes from VRAM containing the tile's properties
    tile_props = bgt + ShiftLeft(start_column, 1&) + ShiftLeft(start_row - tiley, 3&)
    firstbyte = VRAM(tile_props) ' And 255&
    secondbyte = VRAM(tile_props + 1) ' And 255&
    
    '// Priority of tile
    priority = secondbyte And 16&
    
    '// Select Palette (Extended Colors).
    If ((secondbyte And 8&) = 8&) Then pal = 16& Else pal = 0&
    
    '// Pattern Number
    pattern = ShiftLeft(firstbyte + ShiftLeft(secondbyte And 1&, 8&), 5&)
    
    '// Vertical Tile Flip
    If ((secondbyte And 4&) = 0&) Then
      address = ShiftLeft(tiley, 2&) + pattern
    Else
      address = ShiftLeft(7& - tiley, 2&) + pattern
    End If
    
    '// Rowcount
    tilex = 0&
    
    '// Precalculate Y Position
    row_precal = ShiftLeft(Y, 8&)

    address0 = VRAM(address)
    address1 = VRAM(address + 1&)
    address2 = VRAM(address + 2&)
    address3 = VRAM(address + 3&)
    
    '//Plots row of 8 pixels
    bit = 128&
    
    Do
      
      '// Horizontal Tile Flip
      If ((secondbyte And 2&) = 0&) Then
        xpos = tilex + hscroll + X
      Else
        xpos = 7& - tilex + hscroll + X
      End If
      
      colour = 0 '// Set Colour of Pixel (0-15)
      
      If (Not (address0 And bit) = 0&) Then colour = colour Or 1&
      If (Not (address1 And bit) = 0&) Then colour = colour Or 2&
      If (Not (address2 And bit) = 0&) Then colour = colour Or 4&
      If (Not (address3 And bit) = 0&) Then colour = colour Or 8&
      
      '// Set Priority Array (Sprites over background tile)
      If (priority = 16&) And (Not colour = 0&) Then
        bg_priority(xpos) = True
      Else
        bg_priority(xpos) = False
      End If
      
      If Layerdrawbg Then 'checks whether to draw bg from ram
        display(xpos + row_precal) = CRAM(colour + pal)
      Else 'or from user-defined choice, for layer disabling
        display(xpos + row_precal) = QBColor(BG_Color%)
      End If
      
      tilex = tilex + 1&
      bit = ShiftRight(bit, 1&)
    
    Loop Until bit = 0&
    
    start_column = start_column + 1&
    
  Next X
  
End Sub

Private Sub drawsprite(lineno As Long) 'Render Line of Sprite Layer.

  Dim sat As Long, count As Long, Height As Long, zoomed As Boolean, spriteno As Long, Y As Long, address As Long, X As Long, i As Long, row_precal As Long, adr As Long, bit As Long, pixel As Long

  If Not LayerDrawSprites Then 'checks if sprites are disabled
    Exit Sub
  End If
  
  sat = ShiftLeft(vdpreg(5&) And Not 1& And Not &H80&, 7&)
  Height = 8&
  
  '// Enabled 8x16 Sprites
  If ((vdpreg(1) And 2&) = 2&) Then Height = 16&

  '// Enable Zoomed Sprites
  If ((vdpreg(1&) And 1&) = 1&) Then
    Height = ShiftLeft(Height, 1&)
    zoomed = True
  End If
    
  '// Search Sprite Attribute Table (64 Bytes)
  For spriteno = 0& To 63&
    
    If LimitSprites And count >= 8 Then status = status Or &H40&: Exit Sub
    
    Y = VRAM(sat + spriteno)
    
    If (Y = 208&) Then Exit Sub
    
    Y = Y + 1&
    
    If (Y > 240&) Then Y = Y - 256&
    
    If ((lineno >= Y) And ((lineno - Y) < Height)) Then
      
      address = sat + ShiftLeft(spriteno, 1&)
      
      X = VRAM(address + &H80&)
      i = VRAM(address + &H81&)
      
      If ((vdpreg(0&) And 8&) = 8&) Then X = X - 8&
      If ((vdpreg(6&) And 4&) = 4&) Then i = i Or &H100&
      If ((vdpreg(1&) And 2&) = 2&) Then i = i And &H1FE&  'Not 1&
      
      row_precal = ShiftLeft(lineno, 8&)
      
      If zoomed = False Then  '// Normal sprites (Width = 8)
        
        adr = ShiftLeft(i, 5&) + ShiftLeft(lineno - Y, 2&)
        bit = &H80&
          
        Do
          If ((X >= 0&) And (Y >= 0&) And (X <= 255&)) Then
            Call plotspritepixel(X, lineno, X + row_precal, adr, bit)
          End If
          X = X + 1&
          bit = ShiftRight(bit, 1&)
        Loop Until bit = 0&
    
      Else                    '// Zoomed sprites (Width = 16)
    
        adr = ShiftLeft(i, 5&) + ShiftLeft(ShiftRight(lineno - Y, 1&), 2&)
        bit = &H80&
        
        Do
          If ((X + pixel + 1& >= 0) And (Y >= 0&) And (X <= 255&)) Then
            '// Plot Two Pixels
            Call plotspritepixel(X + pixel, lineno, X + pixel + row_precal, adr, bit)
            Call plotspritepixel(X + pixel + 1&, lineno, X + pixel + 1& + row_precal, adr, bit)
          End If
          X = X + 2&
          bit = ShiftRight(bit, 1&)
        Loop Until bit = 0&
        
      End If
      
      count = count + 1&
      
    End If
    
  Next spriteno
  
End Sub
Private Sub plotspritepixel(X As Long, Y As Long, location As Long, address As Long, bit As Long) 'Plot a single sprite pixel.

  Dim colour As Long

  colour = 0&

  If (Not (VRAM(address + 0&) And bit) = 0&) Then colour = colour Or 1&
  If (Not (VRAM(address + 1&) And bit) = 0&) Then colour = colour Or 2&
  If (Not (VRAM(address + 2&) And bit) = 0&) Then colour = colour Or 4&
  If (Not (VRAM(address + 3&) And bit) = 0&) Then colour = colour Or 8&
    
  If (Not (bg_priority(X)) And (Not (colour) = 0&)) Then
    If (Not spritecol(X)) Then
      spritecol(X) = True
      display(location) = CRAM(colour + 16&)
    Else
      status = status Or 32
    End If
  End If

End Sub

Public Sub blankcolumn(lineno As Long)
  
  Dim colour As Long, row_precal As Long, X As Long

  If Layerdrawbg = False Then Exit Sub 'used for layer disabling

  colour = CRAM(16 + (vdpreg(7) And &HF&))
  row_precal = ShiftLeft(lineno, 8)
    
  For X = 8 To 0 Step -1
    display(X + row_precal) = colour
  Next X
    
End Sub
Public Sub interrupts(lineno As Long) 'Generate VDP Interrupts.

  line = lineno
  
  If (lineno <= 192&) Then
  
    '// Frame Interrupt Pending
    If (lineno = 192&) Then
      status = status Or &H80&
      frameint = True
    End If
    
    '// Counter Expired = Line Interrupt Pendind
    If (counter = 0) Then
      counter = vdpreg(10)
      lineint = True
    Else
      '// Otherwise Decrement Counter
      counter = counter - 1
    End If
    
    '// Line Interrupts Enabled and Pending. Assert IRQ Line.
    If (lineint And ((vdpreg(0) And &H10&) = &H10&)) Then
      irqsetLine = True
    End If
  
  '// lineno >= 193
  Else
  
    If (lineno = 193&) And HACK_Spider Then frameint = True '//THIS IS A HACK FOR SPIDERMAN SIN6
    
    '// Reload counter on every line outside active display + 1
    counter = vdpreg(10)
    
    '// Frame Interrupts Enabled and Pending. Assert IRQ Line.
    If (frameint And ((vdpreg(1) And &H20&) = &H20&) And (lineno < 224&)) Then
      irqsetLine = True
    End If
  
  End If

End Sub

Public Function loadpalette() 'calculates the SMS and GG palettes

  Dim i As Long, r As Long, b As Long, g As Long
  
  For i = LBound(SMS_PALETTE) To UBound(SMS_PALETTE)
    r = i And 48&
    g = lshiftlong(i, 2) And 48&
    b = lshiftlong(i, 4) And 48&
    r = lshiftlong(r, 2) Or r Or rshiftlong(r, 2)
    g = lshiftlong(g, 2) Or g Or rshiftlong(g, 2)
    b = lshiftlong(b, 2) Or b Or rshiftlong(b, 2)
    SMS_PALETTE(i) = RGB(r, g, b)
  Next i

  For i = LBound(GG_PALETTE) To UBound(GG_PALETTE)
    r = rshiftlong(i, 4) And &HF0&
    g = i And &HF0&
    b = lshiftlong(i, 4) And &HF0&
    r = r Or rshiftlong(r, 4)
    g = g Or rshiftlong(g, 4)
    b = b Or rshiftlong(b, 4)
    GG_PALETTE(i) = RGB(r, g, b)
  Next i

End Function

